import {timePickerCss} from "./common.style.js";

class OptionsSet {
     arr = [];
     add(v) {
         if (!this.has(v)) {
             this.arr.push(v);
         }
     }
     getAll() {
         return this.arr;
     }
    toggle(v) {
         // if (this.has(v)) {
         //     this.arr.splice(this.arr.indexOf(v), 1);
         // }
         // else {
         //     this.arr.push(v);
         // }
        this.arr = []
        this.arr.push(v);
    }
     has(v) {
         return this.arr.some(i => i === v);
     }
}

class OptionPicker {
    constructor(container, options = []) {
        this.container = container;
        this.options = [];
        this.optionUIS = [];
        this.value = void 0;
        this.values = new OptionsSet()
        this.setOptions(options);
        this.init();
    }

    get selectedIndex() {
        return this.options.findIndex(item => item === this.value);
    }

    get selectedIndexes() {
        let arr = [];
        this.optionUIS.forEach((option, index) => {
            if (this.values.has(option.value)) {
                arr.push(index);
            }
        })
        console.log('OptionPicker selectedIndexes', this.values, this.optionUIS, arr);
        return arr;
    }

    init() {
        this.render();
    }

    setOptions(options) {
        this.options = options;
    }

    setOptionUIS(uis) {
        this.optionUIS = uis;
    }

    render() {
        const columns = document.createElement('div');
        columns.className = 'time-columns';
        columns.setAttribute('part', 'option-columns')

        const hourColumn = this.createTimeColumn('option',
            this.options
        );

        columns.appendChild(hourColumn);

        this.container.innerHTML = '';
        this.container.appendChild(columns);
    }

    createTimeColumn(type, values) {
        const column = document.createElement('div');
        column.className = 'time-column';
        column.setAttribute('part', 'option-column')

        values.forEach((value, index) => {
            const item = document.createElement('div');
            item.className = 'time-item';
            item.dataset[type] = value;
            // console.log(this.optionUIS[index].childNodes)
            let nodes = [...this.optionUIS[index].childNodes].map(v => v.cloneNode(true));
            item.append(...nodes);
            item.addEventListener('click', () => this.selectTime(type, value));
            column.appendChild(item);
        });

        return column;
    }

    selectTime(type, value) {
        this.setValue(value)
        if (this.onSelected) {
            this.onSelected( value, this.values.getAll());
        }
    }

    toString(){
        return this.value
    }

    setValue(v) {
        this.value = v;
        this.values.toggle(v);
    }
}

import {BaseEle, css} from "./core.js"


function getOptions(slotnodes = [], opt = {arr: []}) {
    // console.log(slotnodes)
    slotnodes.forEach((item) => {
        if (Array.isArray(item)) {
            // console.log(item)
            let arr = item.filter(v => {
                return v.nodeName === 'OPTION' || (v.classList && v.classList.contains('option'))
            });
            if (arr.length > 0) {

                opt.arr = opt.arr.concat(arr)
            }
            let slots = item.filter(v => {
                return v.nodeName === 'SLOT'
            }) ;
            if (slots.length > 0) {
                let map = slots.map(v => {
                    return v.assignedNodes().map(v => v.cloneNode(true))
                });
                getOptions(map, opt);
            }
        } else {
            //
        }
    })

}

class ZOptionPicker extends BaseEle {
    constructor() {
        super();
        // console.dir([...this.childNodes])
        this.optionUIS = [...this.childNodes].filter(v => {
            return v.nodeName === 'OPTION'
        }).map(v => v.cloneNode(true))
        this.attachShadow({mode: 'open'});
        this._css= css`
            .timepicker {
                width: max-content;
                border: var(--z-def-border, 1px solid #ccc) ;
                border-radius: var(--z-def-border-radius, 4px);
                padding: 6px;
                box-shadow: var(--z-def-box-shadow, 0 2px 5px rgba(0,0,0,0.1));
                background-color: var(--z-option-picker-bgc, #fff);
                --select-color: var(--z-option-picker-select-color, #fff);
                --select-bg: var(--z-option-picker-select-bgc, var(--z-color-info));
            }

            ${timePickerCss}

            .time-item {
                border-radius: var(--z-def-border-radius, 4px);
                width: var(--z-option-picker-select-item-width, max-content);
            }

            .time-item:hover {
                background-color:   oklch(from  var(--z-option-picker-hover-bgc, #f0f0f0)  calc(l - .07) c h);
                color: var(--z-date-picker-hover-color)
            }
            
            
        //@selected
        `
        this.setCSS(this._css);
        let self = this;
        this._shadowRoot = this.shadowRoot
        this._shadowRoot.innerHTML = '<div id="options" style="display: none;"><slot></slot></div><div id="timepicker" class="timepicker"></div>';
        this.picker = new OptionPicker(
            this.getDomById('timepicker'),
            []
        )
        this.picker.onSelected = function (value, values = [] ) {
            // console.log(parseInt(value[0]))
            self.value = value;
            self.setSelectedStyle();
            self.setLock()
            self.dispatchEvent(new Event('change'));
        }
        this.renderPicker(this.optionUIS)
    }

    get values() {
        return this.picker.values.getAll().join(",");
    }

    setScrollState(value) {
        let self = this;
        let arr = [value]
        for (let i = 0, len = arr.length; i < len; i++) {
            self._shadowRoot.querySelector(`.time-column:nth-child(${i + 1}) .time-item:nth-child(${this.picker.selectedIndex + 1})`).scrollIntoView()
        }
    }

    /**
     *
     */
    setSelectedStyle() {
        let self = this;
        let selectedIndexes = this.picker.selectedIndexes;
        this._log('webcom setSelectedStyle',  self.value, selectedIndexes)
        let cssstr = ''
        for (let i = 0, len = selectedIndexes.length; i < len; i++) {
            cssstr = cssstr +  css`
                    .time-column:nth-child(1) .time-item:nth-child(${selectedIndexes[i] + 1}) {
                        background-color: var(--select-bg) !important;
                        color: var(--select-color);
                    }
                `
        }
        let newcss =    self._css.replace('//@selected',cssstr)
        // console.log(value, cssstr, self);
        self._shadowRoot.adoptedStyleSheets[0].replaceSync(
            newcss
        );
    }

    attrChanged(name, oldValue, newValue) {
        // console.log(name, oldValue, newValue);
        if (this._locks) {
            return
        }
        if (name === 'value') {
            let _val = newValue;
            if (_val && _val.includes(',')) {
                _val = _val.split(',');
            }

            if (Array.isArray(_val)) {
                _val.forEach(v => {
                    this.picker.setValue(v);
                });
                this.value = _val.at(-1)
                this.setSelectedStyle();
            }
            else {
                this.picker.setValue(_val);
                this.value = _val;
                this.setSelectedStyle();
            }
        }
    }

    getOptionFromValue(value) {
        let finded = null;
        this._log('webcom optionpicker getOptionFromValue', this.picker.optionUIS)
        if (Array.isArray(this.picker.optionUIS)) {
            finded = this.picker.optionUIS.find(v => {
                return v.getAttribute('value') === value
            });
            return finded?.cloneNode(true);
        }
        return finded;
    }

    renderPicker(optionUIS = []) {
        let options = optionUIS.map(v => {
            return v.value;
        })
        this._log('webcom optionUIS', optionUIS, options)
        this.picker.setOptionUIS(optionUIS)
        this.picker.setOptions(options)
        this.picker.render()
    }

    onSlotChange(e, {slotnodes} = {}) {
        if (!  this._locks ) {
            this.setLock()
            // console.log('onSlotChange', e, slotnodes);
            let optionUIS = [];
            let ctx = {
                arr: optionUIS,
            }
            getOptions(slotnodes, ctx);
            optionUIS = ctx.arr;
            this.renderPicker(optionUIS)
        }
    }
}

ZOptionPicker.defsel('z-option-picker',{
    attrs: {
        value: '',
    }
});